/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.app.exception;

import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.commons.utils.EmptyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;

/**
 * 统一异常处理
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 处理自定义的业务异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = CoBusinessException.class)
    @ResponseBody
    public Result<Object> coBusinessExceptionHandler(HttpServletRequest req, CoBusinessException e) {
        log.error("【业务异常】", e);
        if (!EmptyUtils.isEmpty(e.getRedissonLock())) {
            // 如果拿到分布式锁,解锁
            e.getRedissonLock().unlock();
        }
        if (!EmptyUtils.isEmpty(e.getErrorData())) {
            return new Result<>(e.getCode(), e.getErrorData());
        }
        return new Result<>(e.getCode());
    }

    /**
     * 处理其他异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result<Object> exceptionHandler(HttpServletRequest req, Exception e) {
        log.error("【系统异常】", e);
        return new Result<>(CoReturnFormat.SYS_ERROR);
    }

    @ExceptionHandler(value = SQLIntegrityConstraintViolationException.class)
    @ResponseBody
    public Result<Object> SQLIntegrityConstraintViolationExceptionHandler(HttpServletRequest req, SQLIntegrityConstraintViolationException e) {
        log.error("【 违反唯一约束】", e);
        return new Result<>(CoReturnFormat.SYS_ERROR);
    }

//  /**
//   * 处理参数验证异常
//   * @param req
//   * @param e
//   * @return
//   */
//  @ExceptionHandler(value = MethodArgumentNotValidException.class)
//  @ResponseBody
//  public Result<Object> methodArgumentNotValidExceptionHandler(HttpServletRequest req, MethodArgumentNotValidException e) {
//    log.error("【参数验证异常】", e);
//    // 获取验证失败的错误信息
//    return new Result<>(CoReturnFormat.PARAM_INVALID);
//  }

    /**
     * 处理@Validated参数校验失败异常
     *
     * @param exception 异常类
     * @return 响应
     */
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result exceptionHandler(MethodArgumentNotValidException exception) {
        String msg = "";
        BindingResult result = exception.getBindingResult();
        StringBuilder stringBuilder = new StringBuilder();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            if (errors != null) {
                errors.forEach(p -> {
                    FieldError fieldError = (FieldError) p;
                    log.error("Bad Request Parameters: {}, field: {}, message: {}",
                            fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
                    stringBuilder.append(fieldError.getDefaultMessage() + ", ");
                });
                String sb = stringBuilder.toString();
                msg = "参数错误：[" + sb.substring(0, sb.lastIndexOf(",")) + "]";
            }
        }
        return Result.validatedException(msg);
    }

}
